#include "Profile.h"

#define TAG "profile"
#define CONFIG_FILE_PATH "/spiffs/config.bin"

dtu_config_t dtu_config;

/**
 * 初始化 SPIFFS 文件系统
 */
void spiffs_init(void) {
	esp_vfs_spiffs_conf_t conf = {.base_path = "/spiffs",
								  .partition_label = NULL,
								  .max_files = 5,
								  .format_if_mount_failed = true};

	esp_err_t ret = esp_vfs_spiffs_register(&conf);
	if (ret != ESP_OK) {
		if (ret == ESP_FAIL) {
			ESP_LOGE(TAG, "Failed to mount or format filesystem");
		} else if (ret == ESP_ERR_NOT_FOUND) {
			ESP_LOGE(TAG, "Failed to find SPIFFS partition");
		} else {
			ESP_LOGE(TAG, "SPIFFS init failed (%s)", esp_err_to_name(ret));
		}
	} else {
		size_t total = 0, used = 0;
		esp_spiffs_info(NULL, &total, &used);
		ESP_LOGI(TAG, "SPIFFS: total: %d, used: %d", total, used);
	}
}

/**
 * 写配置文件
 */
void write_profile(const char *buffer) {
	cJSON *root = cJSON_Parse(buffer);
	if (!root) {
		ESP_LOGE(TAG, "JSON parse error");
		return;
	}

	memset(&dtu_config, 0, sizeof(dtu_config));

	// ===== 解析 basic_parameters =====
	cJSON *basic = cJSON_GetObjectItem(root, "basicParameters");
	if (basic) {
		basic_parameters_t *p = &dtu_config.basic_parameters;
		Helper::copy_cjson_number(&p->network_frame_time, basic, "networkFrameTime");
		Helper::copy_cjson_string(p->config_password, sizeof(p->config_password), basic, "configPassword");
		Helper::copy_cjson_bool(&p->dtu_log_output, basic, "configPassword");
		Helper::copy_cjson_bool(&p->dtu_firmware_update, basic, "dtuFirmwareUpdate");
		Helper::copy_cjson_bool(&p->group_param_update, basic, "groupParamUpdate");
		Helper::copy_cjson_number(&p->auto_reboot_time, basic, "autoRebootTime");
		Helper::copy_cjson_number(&p->serial_inactive_reboot, basic, "serialInactiveReboot");
		Helper::copy_cjson_number(&p->network_inactive_reboot, basic, "networkInactiveReboot");
		Helper::copy_cjson_bool(&p->remote_control, basic, "remoteControl");
		Helper::copy_cjson_number(&p->ntp_sync_interval, basic, "ntpSyncInterval");
		Helper::copy_cjson_bool(&p->new_conn_clear_cache, basic, "newConnClearCache");
		Helper::copy_cjson_bool(&p->low_power_mode, basic, "lowPowerMode");
		Helper::copy_cjson_number(&p->led_indicator, basic, "ledIndicator");
		Helper::copy_cjson_bool(&p->enable_ipv6, basic, "enableIpv6");
	}

	//===== 解析 serial_port_parameters =====
	cJSON *serials = cJSON_GetObjectItem(root, "serialPortParameters");
	if (serials) {
		cJSON *serial = cJSON_GetArrayItem(serials, 0);
		serial_port_parameters_t *p = &dtu_config.serial_port_parameters[0];
		Helper::copy_cjson_bool(&p->enable, serial, "enable");
		if (p->enable) {
			Helper::copy_cjson_number(&p->baud_rate, serial, "baudRate");
			Helper::copy_cjson_number(&p->data_bits, serial, "dataBits");
			Helper::copy_cjson_number(&p->parity, serial, "parity");
			Helper::copy_cjson_number(&p->stop_bits, serial, "stopBits");
			Helper::copy_cjson_number(&p->pack_timeout, serial, "packTimeout");
		}
	}

	// ==== 解析网络通道
	cJSON *networkChannels = cJSON_GetObjectItem(root, "networkChannels");
	if (networkChannels) {
		cJSON *networkChannel = cJSON_GetArrayItem(networkChannels, 0);
		network_channel_t *channel = &dtu_config.network_channels[0];
		network_channel_mqtt_t *p = &dtu_config.network_channel_mqtts[0];
		Helper::copy_cjson_bool(&channel->enable, networkChannel, "enable");
		if (channel->enable) {
			Helper::copy_cjson_string(channel->server_address, sizeof(channel->server_address), networkChannel, "serverAddress");
			Helper::copy_cjson_number(&channel->server_port, networkChannel, "serverPort");
			Helper::copy_cjson_number(&channel->bound_serial, networkChannel, "boundSerial");
			Helper::copy_cjson_number(&channel->type, networkChannel, "type");
			Helper::copy_cjson_number(&p->heartbeat_interval, networkChannel, "heartbeat_interval");
			Helper::copy_cjson_string(p->client_id, sizeof(p->client_id), networkChannel, "clientId");
			Helper::copy_cjson_string(p->username, sizeof(p->username), networkChannel, "username");
			Helper::copy_cjson_string(p->password, sizeof(p->password), networkChannel, "password");
			Helper::copy_cjson_number(&p->protocol_version, networkChannel, "protocolVersion");
			Helper::copy_cjson_bool(&p->persistent_session, networkChannel, "persistentSession");
			Helper::copy_cjson_bool(&p->persistent_message, networkChannel, "persistentMessage");
			Helper::copy_cjson_number(&p->subscribe_qos, networkChannel, "subscribeQos");
			Helper::copy_cjson_number(&p->publish_qos, networkChannel, "publishQos");
			Helper::copy_cjson_string(p->subscribe_topic, sizeof(p->subscribe_topic), networkChannel, "subscribeTopic");
			Helper::copy_cjson_string(p->publish_topic, sizeof(p->publish_topic), networkChannel, "publishTopic");
			Helper::copy_cjson_bool(&p->will_enabled, networkChannel, "willEnabled");
			Helper::copy_cjson_number(&p->will_qos, networkChannel, "willQos");
			Helper::copy_cjson_bool(&p->will_retain, networkChannel, "willRetain");
			Helper::copy_cjson_string(p->will_topic, sizeof(p->will_topic), networkChannel, "willTopic");
			Helper::copy_cjson_string(p->will_message, sizeof(p->will_message), networkChannel, "willMessage");
			Helper::copy_cjson_number(&p->login_info_type, networkChannel, "loginInfoType");
			Helper::copy_cjson_string(p->login_info_content, sizeof(p->login_info_content), networkChannel, "loginInfoContent");
			Helper::copy_cjson_bool(&p->ipv6_support, networkChannel, "ipv6Support");
			Helper::copy_cjson_number(&p->ssl_mode, networkChannel, "sslMode");
		}
	}

	cJSON *dataTemplates = cJSON_GetObjectItem(root, "dataTemplates");
	if (dataTemplates) {
		cJSON *dataTemplate = cJSON_GetArrayItem(dataTemplates, 0);
		data_template_t *p = dtu_config.data_templates;
		Helper::copy_cjson_bool(&p->enable, dataTemplate, "enable");
		if (p->enable) {
			Helper::copy_cjson_string(p->receive_template, sizeof(p->receive_template), dataTemplate, "receiveTemplate");
			Helper::copy_cjson_string(p->send_template, sizeof(p->send_template), dataTemplate, "sendTemplate");
		}
	}

	// ===== 写入 SPIFFS 文件 =====
	FILE *f = fopen(CONFIG_FILE_PATH, "wb");
	if (!f) {
		ESP_LOGE(TAG, "Failed to open config file for writing");
		cJSON_Delete(root);
		return;
	}

	size_t written = fwrite(&dtu_config, 1, sizeof(dtu_config), f);
	fclose(f);

	if (written != sizeof(dtu_config)) {
		ESP_LOGE(TAG, "Failed to write complete config");
	} else {
		ESP_LOGI(TAG, "Config saved to SPIFFS (%s)", CONFIG_FILE_PATH);
	}

	cJSON_Delete(root);
}

/**
 * 读配置文件
 */
dtu_config_t *read_profile(void) {
	memset(&dtu_config, 0, sizeof(dtu_config));

	FILE *f = fopen(CONFIG_FILE_PATH, "rb");
	if (!f) {
		ESP_LOGW(TAG, "Config file not found, using defaults");
		return &dtu_config;
	}

	size_t read_bytes = fread(&dtu_config, 1, sizeof(dtu_config), f);
	fclose(f);

	if (read_bytes != sizeof(dtu_config)) {
		ESP_LOGE(TAG, "Failed to read complete config, using defaults");
		memset(&dtu_config, 0, sizeof(dtu_config));
	} else {
		ESP_LOGI(TAG, "Config loaded from SPIFFS");
	}

	return &dtu_config;
}
